#ifndef	__FK_GDI_H__
#define	__FK_GDI_H__



_FK_BEGIN
class fonts;


// {3C10900A-4DD3-4f20-8DD7-EB5AA01849D5}
//static const GUID IID_FONTS = { 0x3c10900a, 0x4dd3, 0x4f20, { 0x8d, 0xd7, 0xeb, 0x5a, 0xa0, 0x18, 0x49, 0xd5 } };

// {7CF79038-2ECF-49b9-8265-30DEC7A2B75B}
static const GUID IID_FONT = { 0x7cf79038, 0x2ecf, 0x49b9, { 0x82, 0x65, 0x30, 0xde, 0xc7, 0xa2, 0xb7, 0x5b } };

#ifdef __GNUC__

#else   // __GNUC__

///////////////////////////////////////////////////////////////////////////////
// LBitmap
class _FK_OUT_CLASS LBitmap
{
public:
	// Data members
	HBITMAP m_hBitmap;

	// Constructor/destructor/operators
	LBitmap(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap)
	{ }

	~LBitmap()
	{
		if(m_hBitmap != NULL)
			DeleteObject();
	}

	LBitmap operator = (HBITMAP hBitmap)
	{
		Attach(hBitmap);
		return *this;
	}

	void Attach(HBITMAP hBitmap)
	{
		if(m_hBitmap != NULL && m_hBitmap != hBitmap)
			::DeleteObject(m_hBitmap);
		m_hBitmap = hBitmap;
	}

	HBITMAP Detach()
	{
		HBITMAP hBitmap = m_hBitmap;
		m_hBitmap = NULL;
		return hBitmap;
	}

	operator HBITMAP() const { return m_hBitmap; }

	bool IsNull() const { return (m_hBitmap == NULL); }

	// Create and load methods
	HBITMAP LoadBitmap(HINSTANCE hres, LPCTSTR lpszBitmap)
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::LoadBitmap(hres, lpszBitmap);
		return m_hBitmap;
	}

	HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap));
		return m_hBitmap;
	}

#ifndef _WIN32_WCE
	//HBITMAP LoadMappedBitmap(HINSTANCE hres, UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0)
	//{
	//	ATLASSERT(m_hBitmap == NULL);
	//	m_hBitmap = ::CreateMappedBitmap(hres, nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize);
	//	return m_hBitmap;
	//}
#endif // !_WIN32_WCE

	HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, const void* lpBits)
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits);
		return m_hBitmap;
	}

#ifndef _WIN32_WCE
	HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap)
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::CreateBitmapIndirect(lpBitmap);
		return m_hBitmap;
	}
#endif // !_WIN32_WCE

	HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight)
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
		return m_hBitmap;
	}

#ifndef _WIN32_WCE
	HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight)
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight);
		return m_hBitmap;
	}
#endif // !_WIN32_WCE

	virtual BOOL DeleteObject()
	{
		ATLASSERT(m_hBitmap != NULL);
		BOOL bRet = ::DeleteObject(m_hBitmap);
		if(bRet)
			m_hBitmap = NULL;
		return bRet;
	}

	// Attributes
	int GetBitmap(BITMAP* pBitMap) const
	{
		ATLASSERT(m_hBitmap != NULL);
		return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap);
	}

	bool GetBitmap(BITMAP& bm) const
	{
		ATLASSERT(m_hBitmap != NULL);
		return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP));
	}

	bool GetSize(SIZE& size) const
	{
		ATLASSERT(m_hBitmap != NULL);
		BITMAP bm = { 0 };
		if(!GetBitmap(&bm))
			return false;
		size.cx = bm.bmWidth;
		size.cy = bm.bmHeight;
		return true;
	}

#ifndef _WIN32_WCE
	DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const
	{
		ATLASSERT(m_hBitmap != NULL);
		return ::GetBitmapBits(m_hBitmap, dwCount, lpBits);
	}
#endif // !_WIN32_WCE

#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)
	DWORD SetBitmapBits(DWORD dwCount, const void* lpBits)
	{
		ATLASSERT(m_hBitmap != NULL);
		return ::SetBitmapBits(m_hBitmap, dwCount, lpBits);
	}
#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410)

#ifndef _WIN32_WCE
	BOOL GetBitmapDimension(LPSIZE lpSize) const
	{
		ATLASSERT(m_hBitmap != NULL);
		return ::GetBitmapDimensionEx(m_hBitmap, lpSize);
	}

	BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL)
	{
		ATLASSERT(m_hBitmap != NULL);
		return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize);
	}

	// DIB support
	HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse)
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse);
		return m_hBitmap;
	}
#endif // !_WIN32_WCE

	HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset)
	{
		ATLASSERT(m_hBitmap == NULL);
		m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset);
		return m_hBitmap;
	}

#ifndef _WIN32_WCE
	int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines,  LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const
	{
		ATLASSERT(m_hBitmap != NULL);
		return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines,  lpvBits, lpbmi, uColorUse);
	}

	int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse)
	{
		ATLASSERT(m_hBitmap != NULL);
		return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse);
	}
#endif // !_WIN32_WCE
};

class LBitmapHandle : public LBitmap
{
private:
protected:
public:
	//LBitmapHandle(void);
	LBitmapHandle(HBITMAP hBitmap = NULL)
	{
		m_hBitmap = hBitmap;
	}

	virtual ~LBitmapHandle(void)	{   }

	virtual BOOL DeleteObject()
	{
		return TRUE;
	}
};


///////////////////////////////////////////////////////////////////////////////
// CRgn

class LRgn
{
public:
	// Data members
	HRGN m_hRgn;

	// Constructor/destructor/operators
	LRgn(HRGN hRgn = NULL) : m_hRgn(hRgn)
	{ }

	~LRgn()
	{
		if(m_hRgn != NULL)
			DeleteObject();
	}

	LRgn operator =(HRGN hRgn)
	{
		Attach(hRgn);
		return *this;
	}

	void Attach(HRGN hRgn)
	{
		if(m_hRgn != NULL && m_hRgn != hRgn)
			::DeleteObject(m_hRgn);
		m_hRgn = hRgn;
	}

	HRGN Detach()
	{
		HRGN hRgn = m_hRgn;
		m_hRgn = NULL;
		return hRgn;
	}

	operator HRGN() const { return m_hRgn; }

	bool IsNull() const { return (m_hRgn == NULL); }

	// Create methods
	HRGN CreateRectRgn(int x1, int y1, int x2, int y2)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::CreateRectRgn(x1, y1, x2, y2);
		return m_hRgn;
	}

	HRGN CreateRectRgnIndirect(LPCRECT lpRect)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::CreateRectRgnIndirect(lpRect);
		return m_hRgn;
	}

#ifndef _WIN32_WCE
	HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
		return m_hRgn;
	}

	HRGN CreateEllipticRgnIndirect(LPCRECT lpRect)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::CreateEllipticRgnIndirect(lpRect);
		return m_hRgn;
	}

	HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
		return m_hRgn;
	}

	HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
		return m_hRgn;
	}

	HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
		return m_hRgn;
	}

	HRGN CreateFromPath(HDC hDC)
	{
		ATLASSERT(m_hRgn == NULL);
		ATLASSERT(hDC != NULL);
		m_hRgn = ::PathToRegion(hDC);
		return m_hRgn;
	}

	HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
	{
		ATLASSERT(m_hRgn == NULL);
		m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
		return m_hRgn;
	}
#endif // !_WIN32_WCE

	virtual	BOOL DeleteObject()
	{
		ATLASSERT(m_hRgn != NULL);
		BOOL bRet = ::DeleteObject(m_hRgn);
		if(bRet)
			m_hRgn = NULL;
		return bRet;
	}

	// Operations
	void SetRectRgn(int x1, int y1, int x2, int y2)
	{
		ATLASSERT(m_hRgn != NULL);
		::SetRectRgn(m_hRgn, x1, y1, x2, y2);
	}

	void SetRectRgn(LPCRECT lpRect)
	{
		ATLASSERT(m_hRgn != NULL);
		::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
	}

	int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode)
	{
		ATLASSERT(m_hRgn != NULL);
		return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode);
	}

	int CombineRgn(HRGN hRgnSrc, int nCombineMode)
	{
		ATLASSERT(m_hRgn != NULL);
		return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode);
	}

	int CopyRgn(HRGN hRgnSrc)
	{
		ATLASSERT(m_hRgn != NULL);
		return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY);
	}

	BOOL EqualRgn(HRGN hRgn) const
	{
		ATLASSERT(m_hRgn != NULL);
		return ::EqualRgn(m_hRgn, hRgn);
	}

	int OffsetRgn(int x, int y)
	{
		ATLASSERT(m_hRgn != NULL);
		return ::OffsetRgn(m_hRgn, x, y);
	}

	int OffsetRgn(POINT point)
	{
		ATLASSERT(m_hRgn != NULL);
		return ::OffsetRgn(m_hRgn, point.x, point.y);
	}

	int GetRgnBox(LPRECT lpRect) const
	{
		ATLASSERT(m_hRgn != NULL);
		return ::GetRgnBox(m_hRgn, lpRect);
	}

	BOOL PtInRegion(int x, int y) const
	{
		ATLASSERT(m_hRgn != NULL);
		return ::PtInRegion(m_hRgn, x, y);
	}

	BOOL PtInRegion(POINT point) const
	{
		ATLASSERT(m_hRgn != NULL);
		return ::PtInRegion(m_hRgn, point.x, point.y);
	}

	BOOL RectInRegion(LPCRECT lpRect) const
	{
		ATLASSERT(m_hRgn != NULL);
		return ::RectInRegion(m_hRgn, lpRect);
	}

	int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
	{
		ATLASSERT(m_hRgn != NULL);
		return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData);
	}
};

class LRgnHandle : public LRgn
{
private:
protected:
public:
	//LBitmapHandle(void);
	LRgnHandle(HRGN hRgn= NULL)
	{
		m_hRgn = hRgn;
	}
	virtual ~LRgnHandle(void)  { }

	virtual BOOL DeleteObject()
	{
		return TRUE;
	}
};



//
/////////////////////////////////////////////////////////////////////////////////
//// LRgn
//class LRgn
//{
//public:
//	// Data members
//	HRGN m_hRgn;
//
//	// Constructor/destructor/operators
//	LRgn(HRGN hRgn = NULL) : m_hRgn(hRgn)
//	{ }
//
//	~LRgn()
//	{
//		if(m_hRgn != NULL)
//			DeleteObject();
//	}
//
//	LRgn operator =(HRGN hRgn)
//	{
//		Attach(hRgn);
//		return *this;
//	}
//
//	void Attach(HRGN hRgn)
//	{
//		if(m_hRgn != NULL && m_hRgn != hRgn)
//			::DeleteObject(m_hRgn);
//		m_hRgn = hRgn;
//	}
//
//	HRGN Detach()
//	{
//		HRGN hRgn = m_hRgn;
//		m_hRgn = NULL;
//		return hRgn;
//	}
//
//	operator HRGN() const { return m_hRgn; }
//
//	bool IsNull() const { return (m_hRgn == NULL); }
//
//	// Create methods
//	HRGN CreateRectRgn(int x1, int y1, int x2, int y2)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::CreateRectRgn(x1, y1, x2, y2);
//		return m_hRgn;
//	}
//
//	HRGN CreateRectRgnIndirect(LPCRECT lpRect)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::CreateRectRgnIndirect(lpRect);
//		return m_hRgn;
//	}
//
//#ifndef _WIN32_WCE
//	HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2);
//		return m_hRgn;
//	}
//
//	HRGN CreateEllipticRgnIndirect(LPCRECT lpRect)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::CreateEllipticRgnIndirect(lpRect);
//		return m_hRgn;
//	}
//
//	HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode);
//		return m_hRgn;
//	}
//
//	HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode);
//		return m_hRgn;
//	}
//
//	HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3);
//		return m_hRgn;
//	}
//
//	HRGN CreateFromPath(HDC hDC)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		ATLASSERT(hDC != NULL);
//		m_hRgn = ::PathToRegion(hDC);
//		return m_hRgn;
//	}
//
//	HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData)
//	{
//		ATLASSERT(m_hRgn == NULL);
//		m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData);
//		return m_hRgn;
//	}
//#endif // !_WIN32_WCE
//
//	BOOL DeleteObject()
//	{
//		ATLASSERT(m_hRgn != NULL);
//		BOOL bRet = ::DeleteObject(m_hRgn);
//		if(bRet)
//			m_hRgn = NULL;
//		return bRet;
//	}
//
//	// Operations
//	void SetRectRgn(int x1, int y1, int x2, int y2)
//	{
//		ATLASSERT(m_hRgn != NULL);
//		::SetRectRgn(m_hRgn, x1, y1, x2, y2);
//	}
//
//	void SetRectRgn(LPCRECT lpRect)
//	{
//		ATLASSERT(m_hRgn != NULL);
//		::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
//	}
//
//	int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode)
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode);
//	}
//
//	int CombineRgn(HRGN hRgnSrc, int nCombineMode)
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode);
//	}
//
//	int CopyRgn(HRGN hRgnSrc)
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY);
//	}
//
//	BOOL EqualRgn(HRGN hRgn) const
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::EqualRgn(m_hRgn, hRgn);
//	}
//
//	int OffsetRgn(int x, int y)
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::OffsetRgn(m_hRgn, x, y);
//	}
//
//	int OffsetRgn(POINT point)
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::OffsetRgn(m_hRgn, point.x, point.y);
//	}
//
//	int GetRgnBox(LPRECT lpRect) const
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::GetRgnBox(m_hRgn, lpRect);
//	}
//
//	BOOL PtInRegion(int x, int y) const
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::PtInRegion(m_hRgn, x, y);
//	}
//
//	BOOL PtInRegion(POINT point) const
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::PtInRegion(m_hRgn, point.x, point.y);
//	}
//
//	BOOL RectInRegion(LPCRECT lpRect) const
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return ::RectInRegion(m_hRgn, lpRect);
//	}
//
//	int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const
//	{
//		ATLASSERT(m_hRgn != NULL);
//		return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData);
//	}
//};
//

///////////////////////////////////////////////////////////////////////////////
// LDC - The device context class

#endif // __GNUC__

_FK_END

#endif		// __FK_DB_H__

